/*
 * $RCSfile: RoomCourse.java,v $
 * $Revision: 1.1  $
 * $Date: 2012-8-14  $
 *
 * Copyright (C) 2005 Bettem, Inc. All rights reserved.
 *
 * This software is the proprietary information of Bettem, Inc.
 * Use is subject to license terms.
 */
package com.dzpk.gameserver.module.main;
/*
 * $RCSfile: RoomCourse.java,v $
 * $Revision: 1.1  $
 * $Date: 2012-8-14  $
 *
 * Copyright (C) 2005 Bettem, Inc. All rights reserved.
 *
 * This software is the proprietary information of Bettem, Inc.
 * Use is subject to license terms.
 */

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.dzpk.gameserver.action.CommandEnum;
import com.dzpk.gameserver.module.main.room.Room;
import com.dzpk.gameserver.module.main.room.RoomPersion;
import com.dzpk.gameserver.module.main.room.RoomService;
import com.dzpk.gameserver.protocol.MessageStruct;
import org.apache.log4j.Logger;
import sun.plugin2.message.Message;


/**
 * 房间线程
 * <p>Title: RoomCourse</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2006</p>
 *
 * @author shenxing.ruan
 * @version 1.0
 */
public class RoomCourse implements Runnable {
    public static Logger logger = Logger.getLogger(RoomCourse.class);
    //	private long t2 = 0;//房间倒计时
//	private long t3;//玩家倒计时
    private long t4 = System.currentTimeMillis();//玩家应许空房间的时间
    /**
     * 该轮下注 是否有效操作过
     */
    private RoomService roomService;
    private int runType = 0; //0开始 -999 结束
    private Room room;
    private long wiat;
    private long wiat2;

    private int dy = -1;//本轮是否操作过
    private int dyCurrentSize;//本轮第一个操作的人位置

    public static final int size = 2;

    private int isClose = 2;
    private boolean isTT = false;
    private int zuidapaiId = 0;
    private RoomThread roomThread;

    public void setRoomThread(RoomThread roomThread) {
        this.roomThread = roomThread;
    }

    public RoomCourse(Room room) {
        this.room = room;
        roomService = room.getRoomService();
        wiat = 15 * 1000;
        wiat2 = wiat + 2000;
    }

    //1~9个状态 1初始等待发牌状态   2倒计时(发每人两张牌) 3第一轮投注(发三张公共牌) 4第二轮投注(发第四张公共牌) 5第三轮投注(发第五张公共牌) 6第四轮投注 7投注完成 分配奖金
    public void run() {
        try {
            while (runType == 0) {
                switch (room.getRoomStatus()) {
                    case 1:
                        status1();
                        break;
                    case 2:
                        status2();
                        break;
                    case 3:
                        status3();
                        break;
                    case 4:
                        status4();
                        break;
                    case 5:
                        status5();
                        break;
                    case 6:
                        status6();
                        break;
                    case 7:
                        status7();
                        break;
                    default:
                        status10();
                }
                try {
                    synchronized (this) {
                        this.wait(500);
                        roomThread.setOnlineTime(System.currentTimeMillis());
                    }
                } catch (Exception e) {
                    logger.error("线程等待失败....room id is:" + room.getRoomId(), e);
                }
            }
        } catch (Exception e) {
            logger.error("||||||--------------1roomCourse error-----------------||||||");
            try {
                logger.debug("manzhu/damanzhu/roomId/roomStatus/getBisaiStatus:" + room.getManzhuNumber() + "/" + room.getDamanzhuNumber() + "/" + room.getRoomId() + "/" + room.getRoomStatus() + "/" + room.getBisaiStatus());
                logger.debug("room audMap:");
                Object[] audMapObjects = roomThread.getRoom().getAudMap().values().toArray();
                for (Object audObject : audMapObjects) {
                    if (audObject == null) {
                        continue;
                    }
                    RoomPersion rp = (RoomPersion) audObject;
                    logger.debug("userId/chip/nowChip/type/status:" + rp.getUserId() + "/" + rp.getChouma() + "/" + rp.getNowcounma() + "/" + rp.getType() + "/" + rp.getStatus());
                }
                logger.debug("roomPersions :");
                for (RoomPersion rp : roomThread.getRoom().getRoomPersions()) {
                    if (rp == null) {
                        continue;
                    }
                    logger.debug("userId/chip/nowChip/type/status:" + rp.getUserId() + "/" + rp.getChouma() + "/" + rp.getNowcounma() + "/" + rp.getType() + "/" + rp.getStatus());
                }
            } catch (Exception e2) {
                logger.error("roomThreadTrim err + roomid:" + room.getRoomId(), e2);
            }
            logger.error("roomCourse", e);
            e.printStackTrace();
            logger.error("||||||--------------2roomCourse error-----------------||||||");
            try {
                room.getRoomService().closeRoom();
            } catch (Exception e2) {
                logger.error("close room err", e2);
            }

        }

    }

    /**
     * 检测如果有玩家退出 或者掉线就T
     */
    private void diaoxian() {
        //房间没人的关闭该房间
        if (room.getAudMap().size() == 0) {
            if (t4 == 0) {
                t4 = System.currentTimeMillis();
                return;
            }
            //超过60S未有人在整个房间 则关闭房间
            if (System.currentTimeMillis() - t4 > 60 * 1000) {
                // 关闭该房间
                room.getRoomService().closeRoom();
            }
            return;
        } else {
            //20分钟之内还未开始游戏则检测直接关闭房间 放在死进程
            if (System.currentTimeMillis() - t4 > 5 * 60 * 1000) {
                // 关闭该房间
                room.getRoomService().closeRoom();
            }
        }
    }

    //初始化状态
    //对应 站起用户 超时直接删除 坐下用户超时直接踢掉 /没有玩家则直接关闭该房间
    private void status1() {

        diaoxian();

        //监控一旦有两个玩家已经坐下已经准备 则开始倒计时
        int count = 0;
        for (int i = 0; i < room.getRoomPersions().length; i++) {
            if (room.getRoomPersions()[i] != null &&
                    ((room.getRoomType() == 1 && room.getRoomPersions()[i].getNowcounma() >= (room.getFuwufei() + room.getDamanzhu()))
                            || (room.getRoomType() == 2 && room.getRoomPersions()[i].getNowcounma() > 0)
                    )
                    ) {
                count++;
            }
        }

        // 游戏场地
        if (room.getRoomType() == 1) {
            if (count > 1) {
                setT2(System.currentTimeMillis());
                logger.debug("...down user id is : " + " time is :" + System.currentTimeMillis());
                roomService.beginCountdown();
                room.setRoomStatus(2);
            }
        } else {
            // 比赛场地
            if (room.getBisaiStatus() == 1 || room.getBisaiStatus() == 3) {
                //把大小盲注换回来
                room.clearManzhu();
                //有8人开始比赛场
                if (count == size) {
                    //通知开始开始发牌 (发两张底牌) 开局
                    roomService.beginGemeOne();
                    room.setSameKey(System.currentTimeMillis() / 1000);
                }
            } else {
                //通知开始开始发牌 (发两张底牌) 开局
                roomService.beginGemeOne();
            }
        }
    }

    /**
     * 未加钱的T掉
     */
    private void TT() {
        if (!isTT) {
            return;
        } else {
            isTT = false;
        }
        //对于还未添加筹码的人T掉处理 //并通知
        for (int i = 0; i < room.getRoomPersions().length; i++) {
            //
            if (room.getRoomType() == 1) {
                //筹码不够 直接滚蛋
                if (room.getRoomPersions()[i] != null && room.getRoomPersions()[i].getNowcounma() < (room.getFuwufei() + room.getDamanzhu())) {
                    RoomPersion roomPersion = room.getRoomPersions()[i];
                    roomPersion.setType(1);
                    roomPersion.setStatus(0);
                    room.getRoomPersions()[i] = null;
                    //通知别的玩家有人起来了
                    byte[] bytes = MessageStruct.LeaveRoomResp.newBuilder().setIndex(i).setUserId(roomPersion.getUserId()).build().toByteArray();
                    roomService.broadcast(CommandEnum.S2C_LEAVE_ROOM_RESP, bytes);
                    //
//                    if (roomPersion.getUserInfo().getJixiren() == 1) {
//                        logger.error("robot not add chip ....userId :" + roomPersion.getUserId());
//                        room.getAudMap().remove(roomPersion.getUserId());
//                        room.getRobotManage().recoverRobot(new Robot[]{room.getRobotManage().getRobots().get(roomPersion.getUserId())});
//                    }
                }
            } else {
                if (room.getRoomPersions()[i] != null && room.getRoomPersions()[i].getNowcounma() < 1) {
                    RoomPersion roomPersion = room.getRoomPersions()[i];
                    roomPersion.setType(1);
                    roomPersion.setStatus(0);
                    room.getRoomPersions()[i] = null;
                    //通知别的玩家有人起来了
                    byte[] bytes = MessageStruct.LeaveRoomResp.newBuilder().setIndex(i).setUserId(roomPersion.getUserId()).build().toByteArray();
                    roomService.broadcast(CommandEnum.S2C_LEAVE_ROOM_RESP, bytes);
                }
            }
        }
    }

    //倒计时(发每人两张牌)
    private void status2() {
//		diaoxian();
        //判断如果当前座位少于2人 则需要重新等待
        int count = 0;
        for (int i = 0; i < room.getRoomPersions().length; i++) {
            if (room.getRoomPersions()[i] != null && room.getRoomPersions()[i].getNowcounma() >= (room.getFuwufei() + room.getDamanzhu())) {
                count++;
            }
        }
        if (count < 2) {
            room.setRoomStatus(1);//重新开始等待
            return;
        }

//        if (System.currentTimeMillis() - getT2() > Constant.STATUS_2_DC - com.ai.dz.config.Constant.ADD_ROBOT_TIME2) {
//            if (room.getRoomType() == 1 && com.ai.dz.config.Constant.kaiguan) {
//                //为机器人添加筹码携带 只添加一次
//                room.getRobotManage().addChip();
//            }
//        }

        // 机器人控制 机器人添加到5人
        //添加机器人
        int persionCount = room.getRoomPersionCount();
//        if (com.ai.dz.config.Constant.kaiguan && room.getRoomType() == 1 && 0 < persionCount && persionCount < com.ai.dz.config.Constant.ADD_ROBOT_SIZE2) {
//            room.getRobotManage().addRobot(count, 2);
//        }
        //机器人控制
//        //倒计时少于2S时候如果都是机器人房间则关闭房间 只执行一次
//        if (System.currentTimeMillis() - getT2() > Constant.STATUS_2_DC - com.ai.dz.config.Constant.ADD_ROBOT_TIME1) {
//            if (room.getRoomType() == 1 && com.ai.dz.config.Constant.kaiguan) {
//                if (isClose % 2 == 0) {
//                    isClose++;
//                    boolean b = room.getRoomService().closeRobotRoom(room.getRobotManage());
//                    if (b) {
//                        return;
//                    }
//                }
//            }
//        }

        //开始游戏前2秒 还未充值进入 开T 已经倒了5S
        if (System.currentTimeMillis() - getT2() > Constant.STATUS_2_DC - Constant.STATUS_3_DC) {
            TT();
        }
        //倒计时完成
        if (System.currentTimeMillis() - getT2() > Constant.STATUS_2_DC) {
            //通知开始开始发牌 (发两张底牌) 开局
            roomService.beginGemeOne();
            room.setSameKey(System.currentTimeMillis() / 1000);
            //添加记录
//            LogManage.putAllLog(room);
        }
    }

    //第一轮投注(发三张公共牌)
    private void status3() {

        bet(3, 3);
    }

    //第二轮投注(发第四张公共牌)
    private void status4() {
        bet(4, 1);
    }

    //第三轮投注(发第五张公共牌)
    private void status5() {
        bet(5, 1);
    }

    //第四轮投注
    private void status6() {
        bet(6, 0);
    }

    //投注完成分配奖金
    private void status7() {
        if (room.getPocer()[4] == null) {
            int deanCount = 0;
            for (int i = 0; i < 5; i++) {
                if (room.getPocer()[4 - i] == null) {
                    deanCount++;
                } else {
                    break;
                }
            }
            roomService.sendCards(deanCount, -1);
        }
        //比牌 -->通知比牌结果
        Object[] objs = roomService.bipai();
        int winCount = (Integer) objs[0];
        winCount = winCount < 1 ? 1 : winCount;
//		try {
        // 停三秒用户动画播放时间 如果是比赛场地不延迟
        if (room.getRoomType() == 1) {
            synchronized (this) {
                try {
                    this.wait(Constant.BIPAI_TIME + (Constant.WIN_WAIT_TIME * (winCount - 1)));
                } catch (Exception e) {
                    logger.error("wait 10 * 1000 err", e);
                }
            }
//				Thread.sleep();
        }
//		} catch (InterruptedException e) {
//			e.printStackTrace();
//		}
        //重新洗牌 开始新一局
        roomService.nextGame();
//        if (com.ai.dz.config.Constant.kaiguan) {
//            room.getRobotManage().recovery();
//        }
        //设置相关状态
        isClose++;
        isTT = true;
        t4 = System.currentTimeMillis();
    }

    //直接关闭房间
    private void status10() {

    }


    /**
     * @param onWheel   第几轮下注 + 2（当前状态）
     * @param deanCount 下完注发几张公共牌
     */
    private void bet(int onWheel, int deanCount) {

        RoomPersion roomPersion = room.getRoomPersions()[room.getCurrentNumber()];
        if (roomPersion == null) {
            room.getRoomService().closeRoom();
            return;
        }
//        //让机器人人下牌
//        if (com.ai.dz.config.Constant.kaiguan) {
//            room.getRobotManage().aiAction(getT3(), roomPersion);
//        }

        //设置相关状态
        //不用继续比牌了
        if (getT3() == -989) {
            room.setRoomStatus(7);//直接比牌
//			room.getRoomService().nextCurrentNumber();
            //还原相关状态
            client();
            return;
        }


        // 发现掉线 玩家设为弃牌状态 不用通知客户端 发送客户端协议为 该玩家离开的房间（已经操作）
        if (roomPersion.getOnlinerType() == -1) {
            roomPersion.setBetStatus(2);
            roomPersion.setStatus(-2);
            roomPersion.setClientStatus(6);
            newCurrent2(onWheel, deanCount, roomPersion, -1);
        } else {
            //超时
            if (System.currentTimeMillis() - getT3() > wiat2) {
                //托管
                //status = 0; //玩家当前状态 0准备下注/或开始状态  1让牌     2下注 3全下    -1掉线托管  -2第二次拖/或者最后一次发牌掉线()    -3弃牌()
                if (roomPersion.getStatus() == 0 || roomPersion.getStatus() == 1 || roomPersion.getStatus() == 2) {
                    roomPersion.setBetStatus(2);
                    roomPersion.setClientStatus(7);
                    roomPersion.setStatus(-1);
                } else {
                    if (roomPersion.getStatus() == -1) {
                        roomPersion.setBetStatus(2);
                        roomPersion.setClientStatus(6);
                        roomPersion.setStatus(-2);
                    }
                }
                // 通知托管 或者弃牌
                newCurrent2(onWheel, deanCount, roomPersion, 1);
                //未超时
            } else {
                //0 等待下注     1下注并且比上次betChouma有增加     2筹码没有增加
                if (roomPersion.getBetStatus() > 0) {
                    newCurrent2(onWheel, deanCount, roomPersion, -1);
                }
            }
        }
    }

    /**
     * 1、判断玩家家是否需要继续下注-1不需要操作了    1 需要操作但是不用发公共牌     2需要操作但是不用发公共牌
     * 2、发送玩家当前操作（掉线跟退出房间就当中弃牌操作）
     * 3、type == 2 发送公共牌
     *
     * @param onWheel
     * @param deanCount
     * @param roomPersion
     */
    private void newCurrent2(int onWheel, int deanCount, RoomPersion roomPersion, int z) {
        synchronized (roomService) {
            z = 1;
            //下个操作玩家是否还需要操作
            int i = nextCurrent(onWheel, deanCount, roomPersion);
//			room.getRoomService().nextCurrentNumber2();
            if (i < 0) {
                roomService.gameAction(roomPersion.getUserId(), roomPersion.getSize(), roomPersion.getClientStatus(), roomPersion.getAnteNumber(), i, roomPersion.getUserId(), z);
            } else {
                roomService.gameAction(roomPersion.getUserId(), roomPersion.getSize(), roomPersion.getClientStatus(), roomPersion.getAnteNumber(), i == 2 ? -1 : room.getCurrentNumber(), roomPersion.getUserId(), z);
                if (i == 2) {
                    room.anteClean(); //开始下一轮操作
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        logger.debug("开始下一轮线程睡觉出错...", e);

                    }
                    roomService.sendCards2(deanCount, room.getCurrentNumber());
                }
            }
            setT3(System.currentTimeMillis());
        }
    }

    /**
     * @param onWheel   第几轮下注
     * @param deanCount 发几张公告牌
     * @return -1不需要操作了    1 发送当前玩家操作     2本轮结束 发送当前玩家操作 + 下发公共牌
     */
    private int nextCurrent(int onWheel, int deanCount, RoomPersion roomPersion) {
        //本轮是否需要继续下注
        boolean b = true; //true 不需要
        //0 1 2 -1三情况下需要继续下注
        int tem = 0;
        int tem2 = 0;
        RoomPersion p2 = null;
//		logger.debug("------------------------------");
//		logger.debug("maxChip is:" + room.getMaxChouma());
//		for (RoomPersion p : room.getRoomPersions()) {
//			if (p != null) {
//				logger.debug("status/onlinerType/betChouma:" + p.getStatus() + "/" + p.getOnlinerType() + "/" + p.getBetChouma());
//			}
//		}
//		logger.debug("------------------------------");
        for (RoomPersion p : room.getRoomPersions()) {
            if (p != null && p.getOnlinerType() == 1) {
                if (p.getStatus() == 0 || p.getStatus() == 1 || p.getStatus() == 2 || p.getStatus() == -1) {
                    p2 = p;
                    tem++;
                    //判断当前可操作玩家当中是否有 跟最大筹码不同的
                    if (room.getMaxChouma() != p.getBetChouma()) {
                        b = false;
                    }
                } else if (p.getStatus() == 3) {
                    tem2++;
                }
            }
        }
        // 1、当前操作玩家只剩一个并且为本人
        // 2、没有人需要操作
        // 3、最后一个操作玩家的筹码大于当前牌桌最大筹码    或则 没有有效操作的玩家
        if (tem == 0
                || tem == 1 && roomPersion.getUserId() == p2.getUserId()
                || tem == 1 && (p2.getBetChouma() >= room.getMaxChouma() || tem2 == 0)
                ) {
            room.setRoomStatus(7);//直接比牌
//			room.getRoomService().nextCurrentNumber2();
            //还原相关状态
            client();
            return -1;
        }

        //第一轮大家都是
        //都是让牌情况继续下注
        if (dy < 0) {
            dy = 1; //
            wuxiaoCishu = tem - 1;
            dyCurrentSize = roomPersion.getSize();
        }
        if (wuxiaoCishu > 0) {
            if (roomPersion.getBetStatus() == 2) {
                b = false;
                wuxiaoCishu--;
            } else {
                wuxiaoCishu = -1;
            }
        }

        roomPersion.setBetStatus(0);
        room.getRoomService().nextCurrentNumber2();
        //本轮不需要继续下注
        if (b) {
            room.setRoomStatus(onWheel + 1);
            //还原相关状态
            client();
            if (room.getRoomStatus() == 7) {
                return -1;
            } else {
                return 2;
            }
        } else {
            //本论需要继续下注
            return 1;
        }
    }

    private int wuxiaoCishu = 0;

    /**
     * 还原相关状态
     */
    private void client() {
        dy = -1;
        dyCurrentSize = -1;
        room.getRoomService().clearAuneCount();
    }


    public void close() {
        runType = -999;
    }

    /**
     * 个人倒计时
     *
     * @return
     */
    private long getT3() {
        return room.getT3();
    }

    private void setT3(long t3) {
        room.setT3(t3);
    }

    /**
     * 房间倒计时
     *
     * @return
     */
    private long getT2() {
        return room.getT2();
    }

    private void setT2(long t2) {
        room.setT2(t2);
    }

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("1", "1");
        map.put("2", "2");
        map.put("3", "3");
        map.put("4", "4");
        map.put("5", "5");
        Iterator<String> iterator = map.values().iterator();
        while (iterator.hasNext()) {
            String a = iterator.next();
            iterator.remove();
            System.out.println("a is :" + a);
            for (String key : map.keySet()) {
                System.out.println(map.get(key));
            }
            System.out.println("===============");
        }
    }
}

